package com.madou.yy.football;

import com.madou.yy.football.obstacle.Obstacle;
import com.sun.media.jfxmedia.AudioClip;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.io.File;
import java.util.Random;

public class BackgroundPanel extends JPanel implements Runnable {
    static AudioClip CLICK_CLIP;
    static AudioClip WIN_CLIP;
    static AudioClip FAIL_CLIP;
    static AudioClip BG_CLIP;
    static AudioClip STAR_CLIP;
    static {
        try {
            CLICK_CLIP = AudioClip.load(new File(ResourcesUtil.getRootPath()+"\\ball\\tq.wav").toURI());
            WIN_CLIP = AudioClip.load(new File(ResourcesUtil.getRootPath()+"\\ball\\12545.wav").toURI());
            FAIL_CLIP = AudioClip.load(new File(ResourcesUtil.getRootPath()+"\\ball\\5595.wav").toURI());
            BG_CLIP = AudioClip.load(new File(ResourcesUtil.getRootPath()+"\\ball\\8445.wav").toURI());
            STAR_CLIP = AudioClip.load(new File(ResourcesUtil.getRootPath()+"\\ball\\9735.wav").toURI());
            // 播放背景音乐
            BG_CLIP.setLoopCount(-1);
            BG_CLIP.play();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    Color topColor = new Color(25, 54, 88);
    Color personLineColor = new Color(5, 10, 15);
    Color personBgColor = new Color(12, 41, 47);
    Color personBgColor1 = new Color(47, 95, 143);
    Color personBgColor2 = new Color(25, 54, 88);
    Color person2 = new Color(56, 108, 122);
    Color person1 = new Color(114, 150, 164);
    Color bgColor1 = new Color(86, 157, 51);
    Color bgColor2 = new Color(8, 116, 6);
    Color doorColor = new Color(62, 35, 6);
    Color ballBgColor = new Color(50, 107, 30);
    Random random = new Random();
    Thread goalkeeperThread;
    Thread ballThread;
    Result result;
    Ball ball;
    Line line;
    InfoPanel infoPanel;
    public BackgroundPanel(InfoPanel infoPanel){
        this.infoPanel = infoPanel;
        this.setOpaque(false);
        this.setLayout(null);
        line = new Line();
        this.add(line);
    }

    public void setBall(Ball ball){
        this.ball = ball;
        ball.setBounds((getWidth()-64)/2,470,64,64);
        ball.addMouseMotionListener(new MouseAdapter() {
            public void mouseDragged(MouseEvent e){
               int stepX = e.getX();
               int stepY = e.getY();
//                System.out.println(ball.getX()+"\t"+e.getX());
               line.reDraw(ball,BackgroundPanel.this,stepX,stepY,e.isControlDown());
               repaint();
            }
        });
        ball.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                infoPanel.addCount();
                // 用一个线程让球按照瞄准轨迹飞行
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        int star =0;
                        for (Point2D.Double point : line.getPoints()) {
                            ball.setBounds((int) point.x, (int) point.y,ball.getWidth(),ball.getHeight());
                            try {
                                star += obstacleStart();
                                Thread.sleep(100);
                            } catch (InterruptedException ex) {
                                ex.printStackTrace();
                            }
                        }
                        check(star);
                    }
                }).start();
                CLICK_CLIP.play();
            }
        });
    }

    public void clearStar(){
        for (Component component : this.getComponents()) {
            if(component instanceof Star){
                this.remove(component);
            }
        }
    }

    public void setStar(){
        clearStar();
        int count = 10;
        int width = getWidth();
        for (int i = 0; i < count; i++) {
            Star star = new Star();
            star.setBounds(random.nextInt(width==0?300:width),200+random.nextInt(200),48,48);
            this.add(star);
        }
    }

    public int obstacleStart(){
        Rectangle ballBounds = ball.getBounds();
        int tempX[] = {ballBounds.x,ballBounds.x+ballBounds.width,ballBounds.x,ballBounds.x+ballBounds.width};
        int tempY[] = {ballBounds.y,ballBounds.y,ballBounds.y+ballBounds.height,ballBounds.y+ballBounds.height};
        int count = 0;
        for (Component component : this.getComponents()) {
            if(component instanceof Star){
                Star obstacle = (Star)component;
                Rectangle goalkeeperBounds = obstacle.getBounds();
                int minX = goalkeeperBounds.x;
                int maxX = goalkeeperBounds.x+goalkeeperBounds.width;
                int minY = goalkeeperBounds.y;
                int maxY = goalkeeperBounds.y+goalkeeperBounds.height;
                miukoo:for (int i = 0; i < tempY.length; i++) {
                    if(tempX[i]>minX&&tempX[i]<maxX&&tempY[i]>minY&&tempY[i]<maxY){
                        System.out.println("================命中星星");
                        count++;
                        STAR_CLIP.play();
                        this.remove(obstacle);
                        break miukoo;
                    }
                }
            }
        }
        return count;
    }

    public boolean obstacle(){
        Rectangle ballBounds = ball.getBounds();
        int tempX[] = {ballBounds.x,ballBounds.x+ballBounds.width,ballBounds.x,ballBounds.x+ballBounds.width};
        int tempY[] = {ballBounds.y,ballBounds.y,ballBounds.y+ballBounds.height,ballBounds.y+ballBounds.height};
        for (Component component : this.getComponents()) {
            if(component instanceof Obstacle){
                Obstacle obstacle = (Obstacle)component;
                Rectangle goalkeeperBounds = obstacle.getComponent().getBounds();
                int minX = goalkeeperBounds.x;
                int maxX = goalkeeperBounds.x+goalkeeperBounds.width;
                int minY = goalkeeperBounds.y;
                int maxY = goalkeeperBounds.y+goalkeeperBounds.height;
                boolean isLan = false;
                for (int i = 0; i < tempY.length; i++) {
                    if(tempX[i]>minX&&tempX[i]<maxX&&tempY[i]>minY&&tempY[i]<maxY){
                        isLan = true;
                        FAIL_CLIP.play();
                        repaint();
                        JOptionPane.showMessageDialog(null,"球被"+obstacle.name()+"守住了...","Tipe",JOptionPane.ERROR_MESSAGE);
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public void check(int star){
        stop();//停止所有的线程
        Rectangle ballBounds = ball.getBounds();
        boolean isLan = obstacle();
        System.out.println(isLan);
        int x = ballBounds.x;
        int y = ballBounds.y;
        boolean isOut = false;
        if(!isLan) {
            if (x < getWidth() / 5 || x > getWidth() * 4 / 5 || y < 85) {
                isOut = true;
                FAIL_CLIP.play();
                repaint();
                JOptionPane.showMessageDialog(null, "球出界了...", "Tipe", JOptionPane.ERROR_MESSAGE);
            }
        }
        System.out.println(isOut);
        if(!isLan&&!isOut){
            if(result!=null){
                this.remove(result);
            }
            infoPanel.addScore(star);
            System.out.println("===========赢了");
            result = new Result();
            result.setPreferredSize(new Dimension(230,187));
            result.setBounds((getWidth()-230)/2,(getHeight()-187)/2,230,187);
            this.add(result);
            this.repaint();
            WIN_CLIP.play();
            System.out.println(result.getBounds());
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            WIN_CLIP.stop();
            this.remove(result);
        }else{
            FAIL_CLIP.stop();
        }
        line.setVisible(false);
        ball.setBounds((getWidth()-64)/2,470,64,64);
        start();
    }

    public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D)g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        int y = 0;
        g2d.setColor(topColor);
        g2d.fillRect(0,y,getWidth(),10);
        y+=10;
        // 观众背景
        g2d.setColor(personBgColor);
        g2d.fillRect(0,y,getWidth(),100);//画矩形
        for (int i = 0; i < getWidth(); i+=46) {
            // 观众第二排
            g2d.setColor(person2);
            g2d.fillOval(i,36,16,16);//画圆
            g2d.fillArc(i-7,50,30,50,0,180);// 画扇行
            g2d.fillOval(i+24,40,13,13);
            g2d.fillArc(i+18,51,24,49,0,180);
        }
        y+=90;
        // 观众第一排
        g2d.fillRect(0,y-30,getWidth(),50);
        g2d.setColor(person1);
        for (int i = 0; i < getWidth(); i+=46) {
            g2d.fillOval(i+7,y-41,16,16);
            g2d.fillArc(i,y-25,30,50,0,180);
            g2d.fillOval(i+31,y-34,13,13);
            g2d.fillArc(i+25,y-24,24,49,0,180);
        }
        g2d.setColor(personBgColor1);
        g2d.fillRect(0,y,getWidth(),20);
        g2d.setColor(personLineColor);
        g2d.fillRect(0,y,getWidth(),2);
        y+=20;
        g2d.setColor(personBgColor2);
        g2d.fillRect(0,y,getWidth(),18);
        y+=18;
        g2d.setColor(personLineColor);
        g2d.fillRect(0,y,getWidth(),2);
        for (int i = 1; i < 5; i++) {
            g2d.fillRect(getWidth()*i/5,y-38,2,38);
        }
        y+=2;
        // 足球草地
        int count =0;
        int h1=60;
        for (int i = y; i < getHeight(); i++) {
            if(count%2==0){
                g2d.setColor(bgColor1);
            }else{
                g2d.setColor(bgColor2);
            }
            g2d.fillRect(0,y,getWidth(),h1+count*10);
            y+=h1+count*10;
            count++;
        }
        // 禁区
        door(g2d);
        big(g2d);
        small(g2d);
        arc(g2d);
//        // 记时区
        time(g2d);
    }

    private void time(Graphics2D g2d) {
        g2d.setColor(Color.WHITE);
        g2d.fillArc((getWidth()-64)/2-80,460,224,160,0,180);
        g2d.setColor(Color.ORANGE);
        g2d.fillArc((getWidth()-64)/2-80,460,224,160,0,arc);
    }

    private void door(Graphics2D g2d) {
        g2d.setColor(Color.WHITE);
        int step = 15;
        int startX = getWidth()*4/20+20;
        int centerX = getWidth()/2;
        int startY = 85;
        // 球网竖线
        for (int i = startX; i < (getWidth()*4/5); i=startX) {
            int x[] = {startX,startX+(startX<centerX?+8:-8),startX+(startX<centerX?+12:-12)};
            int y[] = {startY,startY+10,155};
            if((centerX-startX)!=-10) {
                g2d.drawPolyline(x, y, x.length);//画折线
            }
            startX+=step;
        }
        // 球迷柱左里
        Stroke stroke = new BasicStroke(5);
        g2d.setStroke(stroke);
        startX = getWidth()*4/20+20;
        int tempX[] = {startX-18,startX-2,startX-2};
        int tempY[] = {startY+3,startY+10,153};
        g2d.drawPolyline(tempX, tempY, tempY.length);
        startX = getWidth()*4/5;
        int rightX[] = {startX-2,startX-20,startX-24};
        int rightY[] = {startY+3,startY+10,153};
        g2d.drawPolyline(rightX, rightY, rightY.length);
        stroke = new BasicStroke(1);
        g2d.setStroke(stroke);
        startX = getWidth()*4/20;
        // 球网横线
        int endX = getWidth()*4/5;
        for (int i = startY; i < 156; i=startY) {
            int x[] = {startX,startX+(startX<centerX?+18:-18),endX-12,endX};
            int y[] = {startY,startY-3,startY-3,startY};
            g2d.drawPolyline(x,y,x.length);
            startY+=step;
        }
        int x[] = {startX,startX+(startX<centerX?+18:-18),endX-12,endX};
        int y[] = {158,155,155,158};
        g2d.drawPolyline(x,y,x.length);
        // 绘制门框
        g2d.setColor(doorColor);
        stroke = new BasicStroke(9);
        g2d.setStroke(stroke);
        g2d.drawRoundRect(getWidth()*4/20,85,getWidth()*3/5,95,20,20);// 带有圆角的矩形
        stroke = new BasicStroke(5);
        g2d.setStroke(stroke);
        g2d.setColor(Color.WHITE);
        g2d.drawRoundRect(getWidth()*4/20,86,getWidth()*3/5,95,20,20);
        g2d.fillRect(0,175,getWidth(),5);
        Font font = new Font("阿里巴巴普惠体 Medium",1,24);
        g2d.setFont(font);
        g2d.setColor(Color.WHITE);
        g2d.drawString("Ctrl + 鼠标： 移动球",30,400);
        g2d.drawString("拖动鼠标： 调整角度",50,440);
        g2d.drawString("点击鼠标： 射门",50,480);
//        g2d.setColor(bgColor1);
//        g2d.fillRect(getWidth()*4/20,180,61,5);
////        g2d.fillRect(getWidth()*4/20+100,180,100,5);
////        g2d.fillRect(getWidth()*16/20,180,100,5);
    }

    public void arc(Graphics2D g2d){
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0,175,getWidth(),5);
        Stroke stroke = new BasicStroke(5);
        g2d.setStroke(stroke);// 设置画笔粗细
        g2d.drawArc(getWidth()*6/20+5,260,getWidth()*8/20,80,0,-180);//扇形
    }

    public void small(Graphics2D g2d){
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0,175,getWidth(),5);
        AffineTransform oldTx = g2d.getTransform();
        Stroke stroke = new BasicStroke(5);
        g2d.setStroke(stroke);
        AffineTransform tx = new AffineTransform();
        tx.setToShear(-0.5, 0);
        g2d.setTransform(tx);
        g2d.drawRoundRect(getWidth()*8/20,175,getWidth()*4/10,50,10,10);
        AffineTransform tx2= new AffineTransform();
        tx2.setToShear(0.5, 0);
        g2d.setTransform(tx2);
        g2d.drawRoundRect(getWidth()*4/20,175,getWidth()*4/10,50,10,10);
        g2d.setTransform(oldTx);
        //清理内部多余的线
        g2d.setColor(bgColor1);
        g2d.fillRect(0,173,getWidth(),2);
        g2d.fillRect(getWidth()*6/20,180,getWidth()*4/10,20);
        g2d.setColor(bgColor2);
        g2d.fillRect(getWidth()*6/20,200,getWidth()*4/10,23);
    }

    public void big(Graphics2D g2d){
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0,175,getWidth(),5);
        AffineTransform oldTx = g2d.getTransform();
        Stroke stroke = new BasicStroke(5);
        g2d.setStroke(stroke);
        AffineTransform tx = new AffineTransform();
        tx.setToShear(-0.5, 0);
        g2d.setTransform(tx);
        g2d.drawRoundRect(getWidth()*5/20,175,getWidth()*6/10,120,10,10);
        AffineTransform tx2= new AffineTransform();
        tx2.setToShear(0.5, 0);
        g2d.setTransform(tx2);
        g2d.drawRoundRect(getWidth()*3/20,175,getWidth()*6/10,120,10,10);
        g2d.setTransform(oldTx);
        //清理内部多余的线
        g2d.setColor(bgColor1);
        g2d.fillRect(0,173,getWidth(),2);
        g2d.fillRect(getWidth()*3/20+10,180,getWidth()*7/10-20,20);
        g2d.fillRect(getWidth()*3/20+10,270,getWidth()*6/10-20,23);
        g2d.setColor(bgColor2);
        g2d.fillRect(getWidth()*3/20+10,200,getWidth()*6/10-20,70);
    }

    public void start() {
        this.goalkeeperThread = new Thread(this);
        goalkeeperThread.start();
        for (Component component : this.getComponents()) {
            if (component instanceof Obstacle) {
                Obstacle obstacle = (Obstacle) component;
                obstacle.start();
            }
        }
        setStar();
    }

    public void stop() {
        if(goalkeeperThread!=null) {
            goalkeeperThread.stop();
        }
        for (Component component : this.getComponents()) {
            if (component instanceof Obstacle) {
                Obstacle obstacle = (Obstacle) component;
                obstacle.stop();
            }
        }
    }

    boolean isBallAdd = true;
    int arc = 0;
    public void run(){
        try {
            while(true) {
                if(isBallAdd){
                    if(arc+10<180){
                        arc+=10;
                        Thread.sleep(200);
                    }else{
                        isBallAdd=false;
                    }
                }else{
                    if(arc-10>=0){
                        arc-=10;
                        Thread.sleep(200);
                    }else{
                        isBallAdd=true;
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
